/*
 * MIT License
 *
 * Copyright (c) 2023 北京凯特伟业科技有限公司
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package com.je.meta.model.view;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.je.common.base.mapper.query.Condition;
import com.je.common.base.mapper.query.Query;
import com.je.common.base.mvc.BaseMethodArgument;
import com.je.common.base.service.QueryBuilderService;
import com.je.common.base.util.DateUtils;
import com.je.common.base.util.StringUtil;
import com.je.ibatis.extension.conditions.ConditionsWrapper;

import java.util.*;

public class QueryConfigVo {
    //tableName
    private String tableName;
    //tableCode
    private String tableCode;
    //查询条件
    private String queryFn;
    //自定义条件
    private String editorFn;
    //排序条件
    private String orderBy;
    //limit
    private int totalSize;
    //前几年、月、日的数据
    private int frontSize;
    //时间类型
    private String frontUnit;
    //基准字段
    private String baseField;
    //基准字段的表code
    private String baseFieldTableCode;
    //字段类型
    private String fieldType;
    //js
    private String jsScript;

    public String getBetweenSqlStr(){
        int frontSize = getFrontSize();
        String baseField = getBaseField();
        String baseFieldTableCode =getBaseFieldTableCode();
        String betweenSql = " AND "+baseFieldTableCode+"."+baseField +" >= '{0}' AND " +baseFieldTableCode+"."+baseField +" <= '{1}'";
        if(frontSize>0&& StringUtil.isNotEmpty(baseField)){
            String startTime ="{startTime}";
            String endTime ="{endTime}";
            return  StringUtil.format(betweenSql,startTime,endTime);
        }
        return "";
    }

    /*public String getStartTime() {
        String startTime = "";
    }*/

    public String getStartTime(){
        int frontSize = getFrontSize();
        String baseField = getBaseField();
       // String baseFieldTableCode =getBaseFieldTableCode();
        //String betweenSql = " AND "+baseFieldTableCode+"."+baseField +" >= '{0}' AND " +baseFieldTableCode+"."+baseField +" <= '{1}'";

        if(frontSize>0&& StringUtil.isNotEmpty(baseField)){
            Date date=null;
            /*String endTime =formatTime(DateUtils.getNow());
            String starTime = "";*/
            String  frontUnit = getFrontUnit();
            switch (frontUnit){
                case DateUtils.YEAR:
                    date= DateUtils.getDateByCalendarType(DateUtils.getNow(),-frontSize, Calendar.YEAR);
                    break;
                case DateUtils.MONTH:
                    date= DateUtils.getDateByCalendarType(DateUtils.getNow(),-frontSize,Calendar.MONTH);
                    break;
                case DateUtils.WEEK:
                    date= DateUtils.getDateByCalendarType(DateUtils.getNow(),-frontSize*7,Calendar.DATE);
                    break;
                case DateUtils.DAY:
                    date= DateUtils.getDateByCalendarType(DateUtils.getNow(),-frontSize,Calendar.DATE);
                    break;
                case DateUtils.HOUR:
                    date= DateUtils.getDateByCalendarType(DateUtils.getNow(),-frontSize,Calendar.HOUR);
                    break;
                default:
                    break;
            }
            if(date!=null){
               return  formatTime(date);
            }
        }
        return "";
    }

    public String formatTime(Date date) {
        String fieldType =getFieldType();
        String time ="";
        switch (fieldType){
            case "date":
                time=  DateUtils.formatDate(date);
                break;
            case "date-time":
                time =DateUtils.formatDateTime(date);
                break;
            case "date-month":
                time =DateUtils.getFormatInstance("yyyy-MM").format(date);
                break;
        }
        return time;
    }

    public String getParameterByJquery(String jquery){
        BaseMethodArgument baseMethodArgument = new BaseMethodArgument();
        baseMethodArgument.setjQuery(queryFn);
        Query query = baseMethodArgument.buildQuery();
        List<Condition> conditions = mixCondition(query);
        JSONArray jsonArray = new JSONArray();
        for(Condition condition:conditions){
            String value = condition.getValue()==null?"":condition.getValue().toString();
            if(value.contains("{")&&!value.contains("@")){
                //说明不是配置的是默认值
                JSONObject parameter = new JSONObject();
                parameter.put("name",condition.getCode());
                jsonArray.add(parameter);
            }
        }
        return jsonArray.toJSONString();
    }


    public String  getSqlByJquery(String jquery, JSONObject parameter, QueryBuilderService queryBuilderService){
        ConditionsWrapper conditionsWrapper = ConditionsWrapper.builder();
        BaseMethodArgument baseMethodArgument = new BaseMethodArgument();
        baseMethodArgument.setjQuery(jquery);
        Query query = baseMethodArgument.buildQuery();
        List<Condition> conditions = mixCondition(query);
        conditionsWrapper.and(conditions != null && !conditions.isEmpty(), i -> {
            conditions.forEach(p -> {
                String value = p.getValue()==null?"":p.getValue().toString();
                String code  = p.getCode();
                if(value.equals("{"+code+"}")){
                    if(parameter!=null&&parameter.containsKey(code)){
                        queryBuilderService.condition(i, p,parameter);
                    }else {
                        queryBuilderService.condition(i, p);
                    }
                }else {
                    queryBuilderService.condition(i, p);
                }
            });
        });
        return conditionsWrapper.getParameterSql();
    }

    public List<Condition> mixCondition(Query query) {
        List<Condition> mixCondition = new ArrayList();
        Optional.ofNullable(query.getTree()).ifPresent(mixCondition::addAll);
        Optional.ofNullable(query.getQuick()).ifPresent(mixCondition::addAll);
        Optional.ofNullable(query.getGroup()).ifPresent(mixCondition::addAll);
        Optional.ofNullable(query.getColumn()).ifPresent(mixCondition::addAll);
        Optional.ofNullable(query.getWorkflow()).ifPresent(mixCondition::addAll);
        Optional.ofNullable(query.getCustom()).ifPresent(mixCondition::addAll);
        return mixCondition;
    }


    public String getTableName() {
        return tableName;
    }

    public void setTableName(String tableName) {
        this.tableName = tableName;
    }

    public String getTableCode() {
        return tableCode;
    }

    public void setTableCode(String tableCode) {
        this.tableCode = tableCode;
    }

    public String getBaseFieldTableCode() {
        return baseFieldTableCode;
    }

    public void setBaseFieldTableCode(String baseFieldTableCode) {
        this.baseFieldTableCode = baseFieldTableCode;
    }

    public String getJsScript() {
        return jsScript;
    }

    public void setJsScript(String jsScript) {
        this.jsScript = jsScript;
    }

    public String getQueryFn() {
        return queryFn;
    }

    public void setQueryFn(String queryFn) {
        this.queryFn = queryFn;
    }

    public String getEditorFn() {
        return editorFn;
    }

    public void setEditorFn(String editorFn) {
        this.editorFn = editorFn;
    }

    public String getOrderBy() {
        return orderBy;
    }

    public void setOrderBy(String orderBy) {
        this.orderBy = orderBy;
    }

    public int getTotalSize() {
        return totalSize;
    }

    public void setTotalSize(int totalSize) {
        this.totalSize = totalSize;
    }

    public int getFrontSize() {
        return frontSize;
    }

    public void setFrontSize(int frontSize) {
        this.frontSize = frontSize;
    }

    public String getFrontUnit() {
        return frontUnit;
    }

    public void setFrontUnit(String frontUnit) {
        this.frontUnit = frontUnit;
    }

    public String getBaseField() {
        return baseField;
    }

    public void setBaseField(String baseField) {
        this.baseField = baseField;
    }

    public String getFieldType() {
        return fieldType;
    }

    public void setFieldType(String fieldType) {
        this.fieldType = fieldType;
    }

}
